
#include <kogi/list.h>

#include <stdlib.h>

// Create/Destroy
int kogi_list_create(struct kogi_list* list)
{
    list->head.next = &(list->tail);
    list->tail.prev = &(list->head);
    list->head.prev = list->tail.next = NULL;
    list->size = 0;
    list->alloc_fp = kogi_standard_alloc_fp;
    list->dealloc_fp = kogi_standard_dealloc_fp;
    list->alloc_context = NULL;
    return 0;
}

int kogi_list_destroy(struct kogi_list* list)
{
    struct kogi_list_node* node = list->head.next;
    while (node != &(list->tail))
    {   struct kogi_list_node* const temp = node->next;
        (*list->dealloc_fp)(list->alloc_context, node);
        node = temp;
    }
    return 0;
}

int kogi_list_push_back(struct kogi_list* list, struct kogi_item item)
{
    struct kogi_list_node* const node = \
        (*list->alloc_fp)(list->alloc_context, sizeof(struct kogi_list_node));
    node->next = &(list->tail);
    node->prev = list->tail.prev;
    node->item = item;
    list->tail.prev->next = node;
    list->tail.prev = node;
    ++(list->size);
    return 0;
}

int kogi_list_push_front(struct kogi_list* list, struct kogi_item item)
{
    struct kogi_list_node* const node = \
        (*list->alloc_fp)(list->alloc_context, sizeof(struct kogi_list_node));
    node->next = list->head.next;
    node->prev = &(list->head);
    node->item = item;
    list->head.next->prev = node;
    list->head.next = node;
    ++(list->size);
    return 0;
}

